// clang-format off

#include "picimage.h"
#include "ui_picimage.h"

#include <QFileInfo>

#include <QClipboard>
#include <QMenu>
#include <QTemporaryFile>
#include <screenutil.h>


PicImage::PicImage(QWidget *parent, MenuRoles role) :
    QWidget(parent),
    ui(new Ui::PicImage),
    mRoles(role),
    manager(new QNetworkAccessManager(this))
{
    ui->setupUi(this);
    picMenuAdd.addAction(ui->addPic);
    picMenuDel.addAction(ui->transPic);
    picMenuAddFromClip.addAction(ui->addFromClip);

    connect(manager, &QNetworkAccessManager::finished, [&](QNetworkReply *reply){
        // QNetworkReply::NetworkError error = reply->error();
        if (reply->error() == QNetworkReply::NetworkError::NoError) {
            int statusCode = reply->attribute(QNetworkRequest::Attribute::HttpStatusCodeAttribute).toInt();
            qDebug() << "Status: " << statusCode;
            if (statusCode == 301) {
                QUrl redirectionUrl = reply->attribute(QNetworkRequest::Attribute::RedirectionTargetAttribute).toUrl();
                qDebug() << "Redirection: (" << redirectionUrl.toString() << ")";
                manager->get(QNetworkRequest(redirectionUrl));
            } else {
                QPixmap pixmap;
                pixmap.loadFromData(reply->readAll());
                if(!pixmap.isNull()) {
                    setImage(pixmap);
                    this->picPath = reply->url().toString();
                    setRemoteReadyRead(true);
                }
                setRemoteFetching(false);
                qDebug() << "URL: (" << this->picPath << ")";
                emit picImageRemoteSignal(true);
            }
        } else {
            this->clean(true);
            emit picImageRemoteSignal(false);
        }
    });

    this->clean(false); // 确保初始状态
}

PicImage::~PicImage()
{
    delete ui;
}

void PicImage::setImage(const QPixmap &picImage, bool isTemporary)
{
    this->picImage = picImage;
    if (isTemporary) {
        qDebug() << "setImage: isTemporary =" << isTemporary;
        if (!tempFile.isOpen())
            tempFile.open();
        picImage.save(&tempFile, "PNG");
        if (tempFile.isOpen())
            tempFile.close();
        setImagePath(tempFile.fileName());
        qDebug() << "setImage: " << tempFile.fileName();
        return;
    }

    ui->label->setPixmap(picImage.scaled(ui->label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
}

QPixmap PicImage::getImage()
{
    return picImage;
}

void PicImage::setImagePath(const QString &picPath)
{
    this->clean();

    qDebug() << "setImagePath: (" << picPath << ")";
    if (isLocalFile(picPath)) {
        QPixmap _pic(picPath);
        if (!_pic.isNull()) {
            ui->label->setPixmap(_pic.scaled(ui->label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
            picImage = _pic;
            this->picPath = picPath;
        }
    } else if (isRemoteFile(picPath)) {
        manager->get(QNetworkRequest(QUrl(picPath)));
        setRemoteFetching(true);
        qDebug() << "REQ: (" << picPath << ")";
    }
}
QString PicImage::getImagePath() const
{
    return picPath;
}

bool PicImage::isEmptyImage()
{
    return picImage.isNull();
}

bool PicImage::isEmptyPath()
{
    return picPath.isEmpty();
}

void PicImage::setMenuRole(PicImage::MenuRoles roles)
{
    mRoles = roles;
}

bool PicImage::isRemoteImage()
{
    if (!isEmptyPath()) {
        return getImagePath().startsWith("http");
    }
    return false;
}

bool PicImage::isLocalImage()
{
    if (!isEmptyPath()) {
        return QFileInfo::exists(getImagePath());
    }
    return false;
}

bool PicImage::isRemoteFile(const QString &urlorfilepath)
{
    if (!isLocalFile(urlorfilepath)) {
        return urlorfilepath.startsWith("http");
    }
    return false;
}

bool PicImage::isLocalFile(const QString &urlorfilepath)
{
    return QFileInfo::exists(urlorfilepath);
}

void PicImage::clean(bool emitDeleted)
{
    if (emitDeleted) emit picImageDeleted();
    this->picImage = QPixmap();
    this->picPath.clear();
    ui->label->setPixmap(picImage);
    ui->label->clear();
    ui->label->setText("+");
    setRemoteReadyRead(false);
    setRemoteFetching(false);
}

bool PicImage::getRemoteReadyRead() const
{
    return remoteReadyRead;
}

void PicImage::setRemoteReadyRead(bool value)
{
    remoteReadyRead = value;
}

bool PicImage::getRemoteFetching() const
{
    return remoteFetching;
}

void PicImage::setRemoteFetching(bool value)
{
    remoteFetching = value;
}

void PicImage::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::MouseButton::LeftButton && !picImage.isNull()) {
        picImagePreview.setPreviewImage(picImage);
        picImagePreview.show();
        ScreenUtil::moveCenterForCursor(picImagePreview);
    }

    if (event->button() == Qt::MouseButton::RightButton && picImage.isNull()) {
        if (mRoles & ShowAdd)
            picMenuAdd.exec(QCursor::pos());
        if (mRoles & ShowAddFromClip)
            picMenuAddFromClip.exec(QCursor::pos());
    }else if (event->button() == Qt::MouseButton::RightButton && !picImage.isNull()) {
        if (mRoles & ShowDel)
            picMenuDel.exec(QCursor::pos());   
    }
}

void PicImage::on_transPic_triggered()
{
    this->clean(true);
}

void PicImage::on_addPic_triggered()
{
   // TODO
}

void PicImage::on_addFromClip_triggered()
{
    QClipboard *clip = qApp->clipboard();
    QPixmap clipPixmap = clip->pixmap(QClipboard::Mode::Clipboard);
    if (!clipPixmap.isNull()) {
        tempFile.open();
        clipPixmap.save(&tempFile, "PNG");
        tempFile.close();
        qDebug() << QString("来源于剪贴板的图片: %1").arg(tempFile.fileName());
        setImagePath(tempFile.fileName());
        emit picImageClipSignal();
    }
}
